﻿using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;

namespace sendfile_server
{
 //     0                   1                   2                   3
 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 //|                     headersize                                | 0-3
 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 //|                        filesize                               | 4-7
 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 //|                     filenamelength                            | 8-11
 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 //|         filename : string                                     |  
 //|                                                               |
 //|         file data : byte[]                                    | 

    class fileinfoHeader
    {
        // 4 byte - headersize
        // 4 byte - filesize
        // 4 byte - filenamelength
        // number bytes - filename 
        int headersize;
        public int Headersize
        {
            get { return headersize; }
            set { headersize = value; }
        }

        int filesize;
        public int Filesize
        {
            get { return filesize; }
            set { filesize = value; }
        }

        int filenamelength;
        public int Filenamelength
        {
            get { return filenamelength; }
            set { filenamelength = value; }
        }

        string filename;
        public string Filename
        {
            get { return filename; }
            set { filename = value; }
        }


        public fileinfoHeader(int _size, int _filenamelength, string _filename)
        {
            filenamelength = _filenamelength;
            filesize = _size;
            filename = _filename;
            headersize = 4 + 4 + 4 + filenamelength;
        }

        /// <summary>
        /// geneate from the filepath
        /// </summary>
        /// <param name="_filepath"></param>
        public fileinfoHeader(string _filepath)
        {
            try
            {
                FileStream fs = new FileStream(_filepath, FileMode.Open, FileAccess.Read);

                filesize = (int)fs.Length;
                filename = fs.Name.Substring(fs.Name.LastIndexOf('\\') + 1);
                filenamelength = filename.Length;
                headersize = 4 + 4 + 4 + filenamelength;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("Open file error! {0}", ex.Message);
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public byte[] GetBytes()
        {
            byte[] buf = new byte[headersize];

            int offset = 0;
            Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(headersize)), 0, buf, offset, 4);
            offset += 4;

            Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(filesize)), 0, buf, offset, 4);
            offset += 4;

            Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(filenamelength)), 0, buf, offset, 4);
            offset += 4;

            Buffer.BlockCopy(Encoding.ASCII.GetBytes(filename), 0, buf, offset, filename.Length);
            offset += filename.Length;

            return buf;
        }

        public void DumpHex()
        {
            Console.WriteLine("------ HEADER INFO ------");
            Console.WriteLine("headersie: {0} ({0:X})", headersize);
            Console.WriteLine("filesize: {0} ({0:X})", filesize);
            Console.WriteLine("filenamesize: {0} ({0:X})", filenamelength);
            Console.WriteLine("filename: {0}", filename);
            foreach (byte b in GetBytes())
            {
                Console.Write("{0:X} ", b);
            }
            Console.WriteLine();
            Console.WriteLine("------ HEADER INFO ------");
        }
    };

    class fileinfoHeader_test
    {
        public static void Test(string _fullpath)
        {
            fileinfoHeader fh = new fileinfoHeader(_fullpath);
            fh.DumpHex();
        }
    }

}